home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
util
/
pack
/
xpkrdcn21.lha
/
xpkRDCN
/
xpkrdcn.c
< prev
Wrap
C/C++ Source or Header
|
1993-04-10
|
4KB
|
172 lines
/* These really aren't necessary.. */
typedef unsigned char uchar;
typedef unsigned short int uint;
#define NO_SUB_PRAGMAS
#define A3000 XPKMF_A3000SPEED
#define HASH_LEN 4096-1 /* Use a 4096 dictionary. If you ever
think of changing this number you
also have to modify the .asm-files.
*/
/* However, since this version only manage a gap of 4098 bytes, a larger
dictionary hardly improves compression. If you apply long-longpatterns
it might be usefull...
*/
#include <string.h>
#include <stdlib.h>
#include <libraries/xpksub.h>
/* Quick assembler unpack routine */
long __asm unpack (register __a0 char *);
uchar *__asm pack_one (register __a0 uint *, register __a1 uchar *,
register __a2 uchar *, register __a3 uchar *, register __a6 uchar **,
register __d6 uchar *);
XMINFO RdcnMode =
{
NULL, /* next */
100, /* upto */
A3000, /* flags */
4, /* packmem */
0, /* unpackmem */
200, /* packspeed, K/sec */
900, /* unpackspeed, K/sec */
320, /* ratio, *0.1% */
0, /* reserved */
"normal" /* description */
};
static struct XpkInfo RdcnInfo =
{
1, /* info version */
0, /* lib version */
0, /* master vers */
0, /* pad */
"RDCN", /* short name */
"Ross Data Compression 2.1", /* long name */
"Packs fatser than BLZW, depacks faster than NUKE", /* description */
0x5244434e, /* 4 letter ID */
XPKIF_PK_CHUNK | XPKIF_UP_CHUNK, /* flags */
65535, /* max in chunk */
0, /* min in chunk */
65500, /* def in chunk */
NULL, /* pk message */
NULL, /* up message */
NULL, /* pk past msg */
NULL, /* up past msg */
100, /* def mode */
0, /* pad */
&RdcnMode /* modes */
};
/*
* Returns an info structure about our packer
*/
struct XpkInfo *__saveds __asm
XpksPackerInfo (void)
{
return &RdcnInfo;
}
void __saveds __asm
XpksPackFree (REG __a0 XPARAMS * xpar)
{
if (xpar->Sub[0] != 0)
{ /* Any dictionary-mem allocated? */
free ((char *) xpar->Sub[0]);
xpar->Sub[0] = 0;
}
}
/*
* This forces the next chunk to be uncompressable independent from the
* previous one. Ie. it clears the hash table
* This really shouldn't be necessary with RDCN, _but_ a future xpkmaster
* _might_ use different memory-chunks for every call to the packer.
*/
long __saveds __asm
XpksPackReset (REG __a0 XPARAMS * xpar)
{
char *ptr = (char *) xpar->Sub[0];
if (ptr != 0)
{
memset (ptr, 0, 4096 * sizeof (uchar **));
}
return 0;
}
void __saveds __asm
XpksUnpackFree (REG __a0 XPARAMS * xpar)
{
/* Decompression does not need any additional data */
}
/* Pack a chunk */
long __saveds __asm
XpksPackChunk (REG __a0 XPARAMS * xpar)
{
uchar **hash_tbl;
uint *ctrl_idx;
uchar *out_idx, *outbuff_end;
uchar *anchor;
uchar *inbuff = xpar->InBuf;
uint inbuff_len = xpar->InLen;
uchar *outbuff = xpar->OutBuf;
uchar *in_idx = inbuff;
uchar *inbuff_end = inbuff + inbuff_len;
hash_tbl = (char **) xpar->Sub[0];
ctrl_idx = (uint *) outbuff;
out_idx = outbuff + sizeof (uint);
outbuff_end = outbuff + xpar->OutBufLen - 48;
if (xpar->Sub[0] == 0)
{
xpar->Sub[0] = (long) calloc (4100, sizeof (uchar **));
hash_tbl = (char **) xpar->Sub[0];
}
/* Skip the compression for a small buffer */
if (inbuff_len <= 18 || xpar->Sub[0] == 0)
return XPKERR_EXPANSION;
/* Scan through inbuff */
anchor = pack_one (ctrl_idx, in_idx, out_idx, inbuff_end, hash_tbl, outbuff_end);
if (anchor == NULL)
return XPKERR_EXPANSION;
xpar->OutLen = anchor - outbuff;
return 0;
}
long __saveds __asm
XpksUnpackChunk (REG __a0 XPARAMS * xpar)
{
long fep;
fep = unpack ((char *)xpar);
return fep;
}